package net.neptech.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.neptech.mapper.InstanceNodeRecordMapper;
import net.neptech.model.dto.InstanceNodeRecordParamDto;
import net.neptech.enums.workflow.InstanceNodeRecordStatusEnum;
import net.neptech.enums.workflow.NodeTypeEnum;
import net.neptech.model.dto.node.Node;
import net.neptech.model.workflow.InstanceNodeRecord;
import net.neptech.model.workflow.InstanceRecord;
import net.neptech.service.InstanceNodeRecordService;
import net.neptech.service.InstanceRecordService;
import net.neptech.util.JsonUtil;
import net.neptech.util.NodeUtil;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Author Saya
 * @Date 2025/8/20 12:05
 * @Description TODO
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class InstanceNodeRecordServiceImpl extends ServiceImpl<InstanceNodeRecordMapper, InstanceNodeRecord> implements InstanceNodeRecordService {
    private final InstanceRecordService instanceRecordService;

    /**
     * 节点开始
     */
    @Override
    public void startNodeEvent(InstanceNodeRecordParamDto instanceNodeRecordParamDto) {
        String flowId = instanceNodeRecordParamDto.getFlowId();
        String nodeId = instanceNodeRecordParamDto.getNodeId();
        String parentNodeId = instanceNodeRecordParamDto.getParentNodeId();
        {
            //判断是否存在同一个节点 执行中了
            Long count = this.lambdaQuery().eq(InstanceNodeRecord::getProcessInstanceId, instanceNodeRecordParamDto.getProcessInstanceId()).eq(InstanceNodeRecord::getNodeId, instanceNodeRecordParamDto.getNodeId()).eq(InstanceNodeRecord::getExecutionId, instanceNodeRecordParamDto.getExecutionId()).eq(InstanceNodeRecord::getStatus, InstanceNodeRecordStatusEnum.ON_GOING.getCode()).count();
            if (count > 0) {
                log.info("有进行中的 不处理了 直接返回");
                return;
            }
        }
        InstanceNodeRecord processNodeRecord = BeanUtil.copyProperties(instanceNodeRecordParamDto, InstanceNodeRecord.class);
        processNodeRecord.setStartTime(new Date());
        processNodeRecord.setStatus(InstanceNodeRecordStatusEnum.ON_GOING.getCode());
        if (instanceNodeRecordParamDto.getNodeType() != null && instanceNodeRecordParamDto.getNodeType() == NodeTypeEnum.END.getValue().intValue()) {
            processNodeRecord.setStatus(InstanceNodeRecordStatusEnum.ENDED.getCode());
        }
        //设置来源的上级id
        String lastNodeId = NodeUtil.getLastNodeId(flowId, nodeId, parentNodeId);
        processNodeRecord.setParentNodeId(lastNodeId);
        save(processNodeRecord);
        //当前流程
        InstanceRecord processInstanceRecord = instanceRecordService.getByInstanceId(instanceNodeRecordParamDto.getProcessInstanceId());
        Node currentProcessRootNode = JsonUtil.parseObject(processInstanceRecord.getProcess(), Node.class);
        log.info("{}-{}上级跳转过来的id:{}", nodeId, instanceNodeRecordParamDto.getNodeName(), parentNodeId);
        //设置executionId
        NodeUtil.handleNodeAddExecutionId(currentProcessRootNode, nodeId, instanceNodeRecordParamDto.getExecutionId());
        processInstanceRecord.setProcess(JsonUtil.toJSONString(currentProcessRootNode));
        instanceRecordService.updateById(processInstanceRecord);
    }

    /**
     * 节点结束
     */
    @Override
    public void endNodeEvent(InstanceNodeRecordParamDto instanceNodeRecordParamDto) {
        String processInstanceId = instanceNodeRecordParamDto.getProcessInstanceId();
        this.lambdaUpdate().set(InstanceNodeRecord::getStatus, InstanceNodeRecordStatusEnum.ENDED.getCode()).set(InstanceNodeRecord::getEndTime, new Date()).set(InstanceNodeRecord::getData, instanceNodeRecordParamDto.getData()).eq(InstanceNodeRecord::getProcessInstanceId, processInstanceId).eq(InstanceNodeRecord::getStatus, InstanceNodeRecordStatusEnum.ON_GOING.getCode()).eq(InstanceNodeRecord::getNodeId, instanceNodeRecordParamDto.getNodeId()).update(new InstanceNodeRecord());
    }

    /**
     * 驳回
     */
    @Override
    public void cancelNodeEvent(InstanceNodeRecordParamDto instanceNodeRecordParamDto) {
        log.info("节点取消：{}-{}", instanceNodeRecordParamDto.getNodeId(), instanceNodeRecordParamDto.getNodeName());
        String processInstanceId = instanceNodeRecordParamDto.getProcessInstanceId();
        String nodeId = instanceNodeRecordParamDto.getNodeId();
        this.lambdaUpdate().set(InstanceNodeRecord::getStatus, InstanceNodeRecordStatusEnum.CANCELED.getCode()).eq(InstanceNodeRecord::getProcessInstanceId, processInstanceId).eq(InstanceNodeRecord::getNodeId, nodeId).eq(InstanceNodeRecord::getStatus, InstanceNodeRecordStatusEnum.ON_GOING.getCode()).update(new InstanceNodeRecord());
    }

    /**
     * 清理数据
     */
    @Override
    public void clearProcess(List<String> flowIdList) {
        this.lambdaUpdate().in(InstanceNodeRecord::getFlowId, flowIdList).remove();
    }
}
